package com.base.data.controller;


import com.base.common.utils.JavaMethod;
import com.base.data.annotations.Delete;
import com.base.data.annotations.Insert;
import com.base.data.annotations.Select;
import com.base.data.annotations.Update;
import com.base.data.tools.SqliteUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.List;


public class SQLMapperProxy implements InvocationHandler {


    public static SQLMapper getSQLMapper() {
        return (SQLMapper) Proxy.newProxyInstance(SQLMapper.class.getClassLoader(), new Class[]{SQLMapper.class}, new SQLMapperProxy());
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (method.isAnnotationPresent(Insert.class)) {

        } else if (method.isAnnotationPresent(Delete.class)) {

        } else if (method.isAnnotationPresent(Update.class)) {
            Update str = method.getAnnotation(Update.class);
            if (args != null && args.length > 0) {
                Object[] args_values = new Object[args.length];
                for (int i = 0; i < args.length; i++) {
                    args_values[i] = JavaMethod.transformClass(args[i], args[i].getClass());
                }

                SqliteUtils.update(str.value(), args_values);
            }


        } else if (method.isAnnotationPresent(Select.class)) {
            Select str = method.getAnnotation(Select.class);

            Class<?> cls;//需要返回的类型
            boolean isOne = false;//是否只有一条

            //获取返回类型
            Type type = method.getGenericReturnType();
            //如果返回类型是一个参数化类型  ps:List<String>
            if (type instanceof ParameterizedType) {
                isOne = false;

                //getActualTypeArguments获取参数化类型的数组，泛型可能有多个
                Type[] params = ((ParameterizedType) type).getActualTypeArguments();
                if (params[0] instanceof Class) {
                    cls = (Class) params[0];
                } else {
                    //返回的类型含有两重参数  ps:List<Map<String,Object>>
                    ParameterizedType pty = (ParameterizedType) params[0];
                    cls = (Class) pty.getRawType();
                }
            }
            //返回的是一个无参数化的类型 ps: ADInfo
            else {
                isOne = true;
                cls = (Class<?>) type;
            }


            List list;//返回的数据
            //如果无参数，全为sql语句，直接执行
            if (args == null || args.length == 0) {
                list = SqliteUtils.rawQuery(cls, str.value());
            }
            //带参数的sql  select * from tabName where fieldName= %1$s  and fieldId= %2$s
            else {
                Object[] args_values = new Object[args.length];
                for (int i = 0; i < args.length; i++) {
                    args_values[i] = JavaMethod.transformClass(args[i], args[i].getClass());
                }
                list = SqliteUtils.find(cls, str.value(), args_values);
            }

            if (isOne) {
                if (list.isEmpty()) {
                    return null;
                } else return list.get(0);
            } else return list;


        }


//        if (method == null) return null;
        if (method.getDeclaringClass() == Object.class)
            return method.invoke(this, args);

        return null;
    }


}